package com.ncepu.clubmanagement.service.impl;

import com.ncepu.clubmanagement.exception.PasswordUnsafeException;
import com.ncepu.clubmanagement.mapper.*;
import com.ncepu.clubmanagement.pojo.*;
import com.ncepu.clubmanagement.pojo.inter.PermissionLevel;
import com.ncepu.clubmanagement.service.ClubService;
import com.ncepu.clubmanagement.service.PersonService;
import com.ncepu.clubmanagement.service.UploadService;
import com.ncepu.clubmanagement.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class PersonServiceImpl implements PersonService {

    @Autowired
    private UploadService uploadService;

    @Autowired
    private PasswordAnalyseUtils passwordAnalyseUtils;

    @Autowired
    private FileSaveUtils fileSaveUtils;

    @Autowired
    private FileNameGenerateUtils fileNameGenerateUtils;

    @Autowired
    private PersonMapper personMapper;

    @Autowired
    private UniversityMapper universityMapper;

    @Autowired
    private AdministratorMapper administratorMapper;

    @Autowired
    private ClubManagementRelationMapper clubManagementRelationMapper; // 社团管理关系表Mapper// 的实例

    @Autowired
    private FileDeleteMapper fileDeleteMapper;

    @Autowired
    private ClubService clubService;

    // 登录逻辑
    @Override
    public Person login(Person person) {
        Person newPerson = personMapper.selectByAccountAndPassword(person);

        return newPerson;
    }

    @Override
    public void register(Person person) throws PasswordUnsafeException {
        if (! passwordAnalyseUtils.isPasswordStrong(person.getPassword())) {
            throw new PasswordUnsafeException();
        }

        personMapper.insert(person);
    }

    @Override
    public PersonWithSchoolName getInfoByAccount(String account) {
        Person person = personMapper.selectByAccountWithoutPassword(account);
        School school = universityMapper.getSchById(person.getSchId());
        PersonWithSchoolName personWithSchoolName = person.toPersonWithSchoolName(school.getSchName());
        return personWithSchoolName;
    }


    // 尽可能保证原子性
//    @Override
//    @Transactional
//    public String updateHeadImage(String account, MultipartFile headImage) throws Exception {
//
//        // 错误处理：如果文件为空，抛出异常
//        if (headImage == null || headImage.isEmpty()) {
//            throw new FileUploadException("文件为空错误！");
//        }
//
//        // 先查询该用户原始头像
//        String url_pre = personMapper.selectHeadImageByAccount(account);
//        // 创建图片名称
//        String originalName = account+"headImage";
//        String name = fileNameGenerateUtils.generateFileName(originalName);
//        // 没有原始url
//        if (url_pre == null) {
//           // 创建路径
//            String path  = "headImage";
//            // 生成图片url但不插入远程
//            url_pre = fileSaveUtils.generateFileUrl(path,name);
//            // 上传url到数据库
//            personMapper.updatePersonImage(url_pre, account);
//        }
//
//        // 有url或已经生成了url
//        // 添加新的头像
//        String url_new = fileSaveUtils.upload(headImage, "headImage", name, url_pre);
//        if (url_new == null) {
//            // 头像上传失败，远端没有处理成功，报错，直接返回
//            throw new FileUploadException();
//        }
//
//        // 成功，返回最终url
//        return url_new;
//    }

    // TODO: 测试这个重构后的方法
    @Override
    @Transactional
    public String updateHeadImage(String account, MultipartFile headImage) throws Exception {
        String url_new = uploadService.universalUploadFile(account, "headImage", headImage,
                () -> personMapper.selectHeadImageByAccount(account),
                url -> personMapper.updatePersonImage(url, account)
                , "headImage"
        );
        return url_new;
    }

    @Override
    public PermissionOfFourLevel getPermissionOfFourLevel(String account) {
        // 先获取id
        int id = personMapper.selectIdByAccount(account);
        // 然后根据id在管理员表进行查询
        Integer permission = administratorMapper.getAdministratorPermissionById(id);
        // 是否存在查询结果
        if (null == permission) {
            // 不是高层次人员
            // 由于是4层次模式，此处需要判断是普通人还是社团管理员
            boolean id2 = clubManagementRelationMapper.isPersonIdExist(id);
            if (!id2) {
                // 返回普通用户权限
                return new PermissionOfFourLevel(PermissionOfFourLevel.PERMISSION_NORMAL);
            }
                // 返回社团管理员级别权限
                return new PermissionOfFourLevel(PermissionOfFourLevel.PERMISSION_CLUB);

        }

        if (permission == 0){
            // 返回后台管理员级别权限
            return new PermissionOfFourLevel(PermissionOfFourLevel.PERMISSION_BACKGROUND);
        }
        else {
            // 返回团委管理员级别权限
            return new PermissionOfFourLevel(PermissionOfFourLevel.PERMISSION_COMMITTEE);
        }

    }

    @Override
    public PermissionOfThreeLevel getPermissionOfThreeLevel(Integer id) {
        // 根据id在管理员表进行查询
        Integer permission = administratorMapper.getAdministratorPermissionById(id);

        // 存在查询结果
        if (null == permission) {
            // 返回普通权限
            return new PermissionOfThreeLevel(PermissionOfThreeLevel.PERMISSION_NORMAL);
        }
        // 否则返回对应权限
        if (permission == 0){
            // 返回后台管理员级别权限
            return new PermissionOfThreeLevel(PermissionOfThreeLevel.PERMISSION_BACKGROUND);
        }
        else {
            // 返回团委管理员级别权限
            return new PermissionOfThreeLevel(PermissionOfThreeLevel.PERMISSION_COMMITTEE);
        }
    }

    @Override
    public void modifyPersonInfo(Person person) {
        personMapper.updatePersonInfo(person);
    }

    @Override
    public List<BasePerson> getAllBasePersonInfoByUserName(String name) {
        List<BasePerson> list = personMapper.selectIdAndNameByName(name);
        return list;
    }

    @Override
    public Boolean isHaveImage(String account) {
        String url = personMapper.selectHeadImageByAccount(account);
        return url != null;
    }

    @Override
    public boolean modifySelfPassword(String account, String password, String newPassword) throws Exception{
        // 原始密码校验
        String passwordFromDatabase = personMapper.selectPasswordByAccount(account);
        if (!password.equals(passwordFromDatabase)) {
            return false;
        }
        // 强度检测
        if (! passwordAnalyseUtils.isPasswordStrong(newPassword)) {
            throw new PasswordUnsafeException();

        }
        // 更新密码
        personMapper.updatePasswordByAccount(newPassword, account);
        return true;
    }

    @Override
    public PageBean getPersonBasicInfoList(Integer page, Integer pageSize, Integer clubId, String userName) {
        PageBean pageBean = PageDivideUtil.toPageBean(() -> personMapper.selectPersonBasicInfoList(clubId, userName),
                page, pageSize);
        return pageBean;
    }

    @Override
    public PageBean getManagedPersonBasicInfoList(Integer page, Integer pageSize, String userName, Integer personId) {
        // 1.先获取管理的所有社团
        List<Integer> clubIds = clubManagementRelationMapper.selectClubIdByManagerId(personId);

        // 2. 根据社团id组和用户名查询人员
        PageBean pageBean = PageDivideUtil.toPageBean(() -> personMapper.selectPersonBasicInfoListByClubIdsAndUserName(clubIds, userName),
                page, pageSize);

        return pageBean;
    }

    @Override
    public void resetPassword(Integer personId) {
        personMapper.updatePasswordById(personId,123456);
    }

    @Override
    public boolean checkIsManaged(Integer sourcePersonId, Integer targetPersonId) {
        // 1. 判定sourcePersonId是否是团委级别权限
        PermissionOfThreeLevel level = getPermissionOfThreeLevel(sourcePersonId);
        if (PermissionLevel.isCommittee(level.getPermissionLevel())){
            return true;
        }
        // 2. 判定是否是自己
        if(Objects.equals(targetPersonId, sourcePersonId)){
            return true;   // 判定是否是自己
        }
        // 3. 判定是否是社团管理的人员
        boolean isManage = clubService.checkIsManagedInClub(sourcePersonId, targetPersonId);
        return isManage;
    }

    @Override
    public PersonFontOfGetDetail getPersonInfoWithoutPassword(Integer targetPersonId) {
        PersonFontOfGetDetail detail = personMapper.selectPersonFontOfGetDetailById(targetPersonId);
        return detail;
    }
}
